package org.sean.generator.init;


import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zaxxer.hikari.HikariDataSource;
import org.sean.framework.util.ObjectUtil;
import org.sean.generator.context.SpringContext;
import org.sean.generator.entity.DataSourceEntity;
import org.sean.generator.service.DataSourceService;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.List;

@Component
public class DataSourceInit implements ApplicationListener<ApplicationReadyEvent> {

    DataSourceService dataSourceService;
    DynamicRoutingDataSource dynamicDataSource;
    private Long lastTime = 0L;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        if (dataSourceService == null) {
            dataSourceService = SpringContext.getBean(DataSourceService.class);
        }

        if (dynamicDataSource == null) {
            dynamicDataSource = SpringContext.getBean(DynamicRoutingDataSource.class);
        }

        if (dataSourceService != null) {
            List<DataSourceEntity> datasources = dataSourceService.list();
            resetDataSource(datasources);
        }
    }

    private void resetDataSource(List<DataSourceEntity> list) {
        if (ObjectUtil.isNotEmpty(list)) {
            list.forEach(ds -> {
                DataSource dataSource = DataSourceBuilder.create(getClass().getClassLoader()).
                        type(HikariDataSource.class)
                        .driverClassName(ds.getDriveClass())
                        .url(ds.getUrl())
                        .username(ds.getUsername())
                        .password(ds.getPassword())
                        .build();
                dynamicDataSource.addDataSource(ds.getId().toString(), dataSource);
                if (ds.getModifyTime().getTime() > lastTime) {
                    lastTime = ds.getModifyTime().getTime();
                }
            });
        }
    }

    /**
     * 数据源定时更新
     */
    @Scheduled(initialDelay = 30_000L, fixedDelay = 60_000L)
    public void updateDataSource() {
        List<DataSourceEntity> list = dataSourceService.list(new LambdaQueryWrapper<DataSourceEntity>()
                .gt(DataSourceEntity::getModifyTime, lastTime));
        resetDataSource(list);
    }
}
